﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TankController.Dominio
{
    public struct Complexo
    {
        private double real;
        private double imaginario;

        public Complexo(double real, double imaginario)
        {
            this.real = real;
            this.imaginario = imaginario;
        }

        public double Real
        {
            get
            {
                return (real);
            }
            set
            {
                real = value;
            }
        }

        public double Imaginario
        {
            get
            {
                return (imaginario);
            }
            set
            {
                imaginario = value;
            }
        }

        public double GetModulo()
        {
            return Math.Sqrt(Math.Pow(real, 2) + Math.Pow(imaginario, 2));
        }

        public double GetFase()
        {
            return Math.Atan(imaginario / real);
        }

        public override string ToString()
        {
            return (String.Format("({0} {1} {2}i)", real, Math.Sign(imaginario) > -1 ? '+' : '-', Math.Abs(imaginario)));
        }

        public static bool operator ==(Complexo c1, Complexo c2)
        {
            if ((c1.real == c2.real) && (c1.imaginario == c2.imaginario))
                return (true);
            else
                return (false);
        }

        public static bool operator !=(Complexo c1, Complexo c2)
        {
            return (!(c1 == c2));
        }

        public override bool Equals(object o2)
        {
            Complexo c2 = (Complexo)o2;

            return (this == c2);
        }

        public override int GetHashCode()
        {
            return (real.GetHashCode() ^ imaginario.GetHashCode());
        }

        public static Complexo operator +(Complexo c1, Complexo c2)
        {
            return (new Complexo(c1.real + c2.real, c1.imaginario + c2.imaginario));
        }

        public static Complexo operator -(Complexo c1, Complexo c2)
        {
            return (new Complexo(c1.real - c2.real, c1.imaginario - c2.imaginario));
        }

        public static Complexo operator *(Complexo c1, Complexo c2)
        {
            return (new Complexo(c1.real * c2.real - c1.imaginario * c2.imaginario,
            c1.real * c2.imaginario + c2.real * c1.imaginario));
        }

        public static Complexo operator /(Complexo c1, Complexo c2)
        {
            if ((c2.real == 0.0f) && (c2.imaginario == 0.0f))
                throw new DivideByZeroException("Não é possível dividir um número Complexo por zero.");

            double novoReal = (c1.real * c2.real + c1.imaginario * c2.imaginario) / (c2.real * c2.real + c2.imaginario * c2.imaginario);
            double novoImaginario = (c2.real * c1.imaginario - c1.real * c2.imaginario) / (c2.real * c2.real + c2.imaginario * c2.imaginario);

            return (new Complexo(novoReal, novoImaginario));
        }
    }
}
